package mybatis;

import java.math.BigDecimal;
import java.sql.Types;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.JavaTypeResolver;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.config.Context;
import org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl.JdbcTypeInformation;

public class MyJavaTypeResolver implements JavaTypeResolver {
	protected Map<Integer, JdbcTypeInformation> typeMap;

	public MyJavaTypeResolver() {
		this.typeMap = new HashMap<Integer, JdbcTypeInformation>();

		this.typeMap.put(Integer.valueOf(2003), new JdbcTypeInformation("ARRAY", new FullyQualifiedJavaType(Object.class.getName())));
		this.typeMap.put(Integer.valueOf(-5), new JdbcTypeInformation("BIGINT", new FullyQualifiedJavaType(Long.class.getName())));
		this.typeMap.put(Integer.valueOf(-2), new JdbcTypeInformation("BINARY", new FullyQualifiedJavaType("byte[]")));

		this.typeMap.put(Integer.valueOf(-7), new JdbcTypeInformation("BIT", new FullyQualifiedJavaType(Boolean.class.getName())));
		this.typeMap.put(Integer.valueOf(2004), new JdbcTypeInformation("BLOB", new FullyQualifiedJavaType("byte[]")));

		this.typeMap.put(Integer.valueOf(16), new JdbcTypeInformation("BOOLEAN", new FullyQualifiedJavaType(Boolean.class.getName())));
		this.typeMap.put(Integer.valueOf(1), new JdbcTypeInformation("CHAR", new FullyQualifiedJavaType(String.class.getName())));
		this.typeMap.put(Integer.valueOf(2005), new JdbcTypeInformation("VARCHAR"/* "CLOB" */, new FullyQualifiedJavaType(String.class.getName())));
		this.typeMap.put(Integer.valueOf(70), new JdbcTypeInformation("DATALINK", new FullyQualifiedJavaType(Object.class.getName())));
		this.typeMap.put(Integer.valueOf(91), new JdbcTypeInformation("DATE", new FullyQualifiedJavaType(Date.class.getName())));
		// this.typeMap.put(Integer.valueOf(3), new JdbcTypeInformation("DECIMAL", new
		// FullyQualifiedJavaType(BigDecimal.class.getName())));
		this.typeMap.put(Integer.valueOf(2001), new JdbcTypeInformation("DISTINCT", new FullyQualifiedJavaType(Object.class.getName())));
		this.typeMap.put(Integer.valueOf(8), new JdbcTypeInformation("DOUBLE", new FullyQualifiedJavaType(Double.class.getName())));
		this.typeMap.put(Integer.valueOf(6), new JdbcTypeInformation("FLOAT", new FullyQualifiedJavaType(Double.class.getName())));
		this.typeMap.put(Integer.valueOf(4), new JdbcTypeInformation("INTEGER", new FullyQualifiedJavaType(Integer.class.getName())));
		this.typeMap.put(Integer.valueOf(2000), new JdbcTypeInformation("JAVA_OBJECT", new FullyQualifiedJavaType(Object.class.getName())));
		this.typeMap.put(Integer.valueOf(-16), new JdbcTypeInformation("LONGNVARCHAR", new FullyQualifiedJavaType(String.class.getName())));
		this.typeMap.put(Integer.valueOf(-4), new JdbcTypeInformation("LONGVARBINARY", new FullyQualifiedJavaType("byte[]")));

		this.typeMap.put(Integer.valueOf(-1), new JdbcTypeInformation("LONGVARCHAR", new FullyQualifiedJavaType(String.class.getName())));
		this.typeMap.put(Integer.valueOf(-15), new JdbcTypeInformation("NCHAR", new FullyQualifiedJavaType(String.class.getName())));
		this.typeMap.put(Integer.valueOf(2011), new JdbcTypeInformation("NCLOB", new FullyQualifiedJavaType(String.class.getName())));
		this.typeMap.put(Integer.valueOf(-9), new JdbcTypeInformation("NVARCHAR", new FullyQualifiedJavaType(String.class.getName())));
		this.typeMap.put(Integer.valueOf(0), new JdbcTypeInformation("NULL", new FullyQualifiedJavaType(Object.class.getName())));
		// this.typeMap.put(Integer.valueOf(2), new JdbcTypeInformation("NUMERIC", new
		// FullyQualifiedJavaType(BigDecimal.class.getName())));
		this.typeMap.put(Integer.valueOf(1111), new JdbcTypeInformation("OTHER", new FullyQualifiedJavaType(Object.class.getName())));
		this.typeMap.put(Integer.valueOf(7), new JdbcTypeInformation("REAL", new FullyQualifiedJavaType(Float.class.getName())));
		this.typeMap.put(Integer.valueOf(2006), new JdbcTypeInformation("REF", new FullyQualifiedJavaType(Object.class.getName())));
		this.typeMap.put(Integer.valueOf(5), new JdbcTypeInformation("SMALLINT", new FullyQualifiedJavaType(Short.class.getName())));
		this.typeMap.put(Integer.valueOf(2002), new JdbcTypeInformation("STRUCT", new FullyQualifiedJavaType(Object.class.getName())));
		this.typeMap.put(Integer.valueOf(92), new JdbcTypeInformation("TIME", new FullyQualifiedJavaType(Date.class.getName())));
		this.typeMap.put(Integer.valueOf(93), new JdbcTypeInformation("TIMESTAMP", new FullyQualifiedJavaType(Date.class.getName())));
		this.typeMap.put(Integer.valueOf(-6), new JdbcTypeInformation("TINYINT", new FullyQualifiedJavaType(Byte.class.getName())));
		this.typeMap.put(Integer.valueOf(-3), new JdbcTypeInformation("VARBINARY", new FullyQualifiedJavaType("byte[]")));

		this.typeMap.put(Integer.valueOf(12), new JdbcTypeInformation("VARCHAR", new FullyQualifiedJavaType(String.class.getName())));
	}

	public FullyQualifiedJavaType calculateJavaType(IntrospectedColumn introspectedColumn) {
		FullyQualifiedJavaType answer;
		JdbcTypeInformation jdbcTypeInformation = (JdbcTypeInformation) typeMap.get(introspectedColumn.getJdbcType());
		if (jdbcTypeInformation == null) {
			switch (introspectedColumn.getJdbcType()) {
			case Types.DECIMAL:
			case Types.NUMERIC:
				if (introspectedColumn.getScale() > 0) {// 如果包含小数点则转换成float
					answer = new FullyQualifiedJavaType(Float.class.getName());
				} else {
					if (introspectedColumn.getLength() > 18 /* || forceBigDecimals */) {
						answer = new FullyQualifiedJavaType(BigDecimal.class.getName());
					} else {
						answer = new FullyQualifiedJavaType(Integer.class.getName());
					}
				}

				break;
			default:
				answer = null;
				break;
			}
		} else {
			answer = jdbcTypeInformation.getFullyQualifiedJavaType();
		}
		return answer;
	}

	@Override
	public void addConfigurationProperties(Properties arg0) {
	}

	@Override
	public String calculateJdbcTypeName(IntrospectedColumn arg0) {
		String answer = null;

		JdbcTypeInformation jdbcTypeInformation = (JdbcTypeInformation) this.typeMap.get(Integer.valueOf(arg0.getJdbcType()));

		if (jdbcTypeInformation != null) {
			answer = jdbcTypeInformation.getJdbcTypeName();
		}
		if (answer == null) {
			answer = "DECIMAL";
		}
		return answer;
	}

	@Override
	public void setContext(Context arg0) {
	}

	@Override
	public void setWarnings(List<String> arg0) {
	}
}
